﻿using System.AutoUpdate.Core;
using System.AutoUpdate.Core.Operations;
using System.AutoUpdate.Library;
using System.CodeDom.Compiler;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;

using Microsoft.CSharp;

namespace System.AutoUpdate.Operations
{
    
    /// <summary>
    /// Compiles and runs bootstrap application that replaces files
    /// </summary>
    public class ApplyOperation : BasicOperation
    {
        public override bool StartOperation (UpdateInfo info)
        {
            if (info == null)
            {
                return false;
            }


            OperationEvent (Core.OperationEvent.Started, this, new OperationEventArgs ());

            //
            // Create compiler parameters
            //
            string[] referenceAssemblies = { "System.dll", "WindowsBase.dll" };

            CompilerParameters compilerparams = new CompilerParameters (referenceAssemblies, "UpdateBootstrap.exe")
                                                {
                                                    GenerateExecutable = true,
                                                    MainClass = "UpdateBootstrap",
                                                    OutputAssembly = "UpdateBootstrap",
                                                    GenerateInMemory = true
                                                };

            Assembly assembly = Assembly.GetExecutingAssembly();

            Stream stream = assembly.GetManifestResourceStream ("System.AutoUpdate.Bootstrap.UpdateBootstrap.cs");
            
            if (stream != null)
            {
                StreamReader textStreamReader = new StreamReader(stream);

                CodeDomProvider compiler = new CSharpCodeProvider();
                CompilerResults results = compiler.CompileAssemblyFromSource(compilerparams, textStreamReader.ReadToEnd ());

                //
                // Errors during compilation
                //

                if (results.Errors.HasErrors)
                {
                    StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");

                    foreach (CompilerError error in results.Errors)
                    {
                        errors.AppendFormat("Line {0},{1}\t: {2}\n", error.Line, error.Column, error.ErrorText);
                    }

                    OperationEvent(Core.OperationEvent.Completed, this, new OperationEventArgs
                                                                        {
                                                                            Exception = new Exception(errors.ToString())
                                                                        });

                    return false;
                }

                //
                // No errors, yay, start the process!
                //

                ProcessStartInfo start = new ProcessStartInfo("UpdateBootstrap.exe")
                                         {
                                             CreateNoWindow = true,
                                             WindowStyle = ProcessWindowStyle.Hidden,
                                             RedirectStandardInput = true,
                                             RedirectStandardOutput = true,
                                             Arguments = "\"" + info.TemporaryDirectory + "\" \"" + Path.GetFileName (Assembly.GetEntryAssembly ().Location) + "\" \"" + Info.ApplicationRoot + "\""
                                         };

                Process.Start (start);

                OperationEvent(Core.OperationEvent.Completed, this, new OperationEventArgs());

                //
                // Shutdown the application
                //

                //Environment.Exit (0);
            }
            
            return false;
        }
    }
}
